using Infrastructure.AliyunOSS;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Generic;
using RabbitTraceability.Api.Dtos.Response;
using Domain;
using Infrastructure;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using RabbitTraceability.Api.Applications.Command;
using RabbitTraceability.Api.Applications.CommandHandler;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using ErrorCode;
using Microsoft.IdentityModel.Protocols.OpenIdConnect.Configuration;
using SkiaSharp;
using System.Security.AccessControl;
using QiNiuStorage;
using Microsoft.IdentityModel.Tokens.Experimental;
using Microsoft.AspNetCore.WebUtilities;
using MediatR;
using System.Text.RegularExpressions;

namespace RabbitTraceability.Api.Controllers
{
    /// <summary>
    /// 图片上传控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class ImageController : ControllerBase
    {
        private readonly IAliyunOSSService _ossService;
        private readonly ILogger<ImageController> _logger;
        private readonly IRepository<ImageInfo> _imageRepository;
        private readonly IConfiguration _sysConfig;



        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ossService">阿里云OSS服务</param>
        /// <param name="logger">日志记录器</param>
        /// <param name="imageRepository">图片信息仓储</param>
        public ImageController(
            IAliyunOSSService ossService,
            ILogger<ImageController> logger,
            IRepository<ImageInfo> imageRepository,
             IConfiguration sysConfig)
        {
            _ossService = ossService;
            _logger = logger;
            _imageRepository = imageRepository;
            _sysConfig = sysConfig;

        }

        /// <summary>
        /// 上传单张图片
        /// </summary>
        /// <param name="file">图片文件</param>
        /// <param name="bucketName">存储桶名称（必填）</param>
        /// <returns>上传结果</returns>
        [HttpPost]
        [RequestSizeLimit(10 * 1024 * 1024)] // 限制10MB
        public async Task<IActionResult> Upload(
            IFormFile file,
            [FromQuery] string bucketName)
        {

            if (file == null || file.Length == 0)
            {
                //错误请求BadRequest
                return BadRequest(new { success = false, message = "请选择图片文件" });
            }

            if (string.IsNullOrEmpty(bucketName))
            {
                return BadRequest(new { success = false, message = "存储桶名称不能为空" });
            }
            // 检查文件类型
            string contentType = file.ContentType?.ToLower() ?? "";
            if (!contentType.StartsWith("image/"))
            {
                return BadRequest(new { success = false, message = "只允许上传图片文件" });
            }
            try
            {
                // 生成文件名
                string fileExt = Path.GetExtension(file.FileName).ToLowerInvariant();
                string fileName = $"{Guid.NewGuid():N}{fileExt}";

                // 按日期组织文件路径
                string objectName = $"images/{DateTime.Now:yyyy/MM/dd}/{fileName}";
                // 上传文件
                using var stream = file.OpenReadStream();
                var ossType = int.Parse(_sysConfig["OSSType:OSSKey"].ToString());
                if (ossType == 1)
                {
                    string ak = _sysConfig["OSSType:Qiniu:AccessKey"];
                    string sk = _sysConfig["OSSType:Qiniu:SecretKey"];
                    string baseUrl = _sysConfig["OSSType:Qiniu:BaseUrl"];
                    string pathFile = file.FileName;
                    string bucket = "Images/traceabilityImg/" + fileName;
                    var result = await QiNiuHelper.QiNiuUploadFile(ak, sk, bucket, pathFile, baseUrl, stream);
                    var response = new ImageUploadResponseDto
                    {
                        ImageUrl = result.Url ?? string.Empty,
                        RelativePath = result.Url ?? string.Empty,
                        FileName = fileName,
                        FileSize = file.Length
                    };
                    return Ok(new
                    {
                        success = true,
                        data = response,
                    });
                }
                else
                {
                    var result = await _ossService.UploadAsync(bucketName, objectName, stream, file.ContentType);
                    if (result.Success)
                    {
                        _logger.LogInformation("图片上传成功：{BucketName}/{ObjectName}", bucketName, result.ObjectName);

                        // 使用标准的响应DTO
                        var response = new ImageUploadResponseDto
                        {
                            ImageUrl = result.Url ?? string.Empty,
                            RelativePath = result.ObjectName ?? string.Empty,
                            FileName = fileName,
                            FileSize = file.Length
                        };

                        return Ok(new
                        {
                            success = true,
                            data = response
                        });
                    }
                    else
                    {
                        _logger.LogError("图片上传失败：{BucketName}/{ErrorMessage}", bucketName, result.ErrorMessage);
                        return StatusCode(500, new { success = false, message = "图片上传失败", error = result.ErrorMessage });
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "图片上传过程中发生错误：{BucketName}", bucketName);
                return StatusCode(500, new { success = false, message = "图片上传过程中发生错误", error = ex.Message });
            }
        }

        /// <summary>
        /// 上传多张图片
        /// </summary>
        /// <param name="bucketName">存储桶名称（必填）</param>
        /// <param name="imageCategory">图片分类（如：养殖环境/生产加工/检验报告）</param>
        /// <param name="productionBatch">关联的生产批次</param>
        /// <returns>上传结果</returns>
        [HttpPost]
        [RequestSizeLimit(50 * 1024 * 1024)] // 限制50MB
        public async Task<IActionResult> UploadMultiple(
            [FromQuery] string bucketName,
            [FromQuery] string imageCategory = "",
            [FromQuery] string productionBatch = "")
        {
            if (string.IsNullOrEmpty(bucketName))
            {
                return BadRequest(new { success = false, message = "存储桶名称不能为空" });
            }

            var files = Request.Form.Files;
            if (files == null || files.Count == 0)
            {
                return BadRequest(new { success = false, message = "请选择图片文件" });
            }

            var results = new List<object>();
            var successResults = new List<ImageUploadResponseDto>();
            var failedCount = 0;
            var savedImages = new List<ImageInfo>();

            foreach (var file in files)
            {
                // 检查文件类型
                string contentType = file.ContentType?.ToLower() ?? "";
                if (!contentType.StartsWith("image/"))
                {
                    results.Add(new
                    {
                        fileName = file.FileName,
                        success = false,
                        message = "只允许上传图片文件"
                    });
                    failedCount++;
                    continue;
                }

                try
                {
                    // 生成文件名
                    string fileExt = Path.GetExtension(file.FileName).ToLowerInvariant();
                    string fileName = $"{Guid.NewGuid():N}{fileExt}";

                    // 按日期组织文件路径
                    string objectName = $"images/{DateTime.Now:yyyy/MM/dd}/{fileName}";

                    // 上传文件
                    using var stream = file.OpenReadStream();
                    string ak = _sysConfig["OSSType:Qiniu:AccessKey"];
                    string sk = _sysConfig["OSSType:Qiniu:SecretKey"];
                    //string bucket = _sysConfig["OSSType:Qiniu:Bucket"];
                    string baseUrl = _sysConfig["OSSType:Qiniu:BaseUrl"];
                    string pathFile = file.FileName;


                    string bucket = "Images/traceabilityImg/" + fileName;
                    var result = await QiNiuHelper.QiNiuUploadFile(ak, sk, bucket, pathFile, baseUrl, stream);
                   // var result = await _ossService.UploadAsync(bucketName, objectName, stream, file.ContentType);

                    if (result.Success==true)
                    {
             

                        var imageResponse = new ImageUploadResponseDto
                        {
                            ImageUrl = result.Url ?? string.Empty,
                            RelativePath = result.Url ?? string.Empty,
                            FileName = fileName,
                            FileSize = file.Length
                        };

                        // 创建图片信息并保存到数据库
                        var imageInfo = new ImageInfo
                        {
                            ImageCategory = imageCategory,
                            ImageUrl = result.Url ?? string.Empty,
                            ProductionBatch = productionBatch
                        };

                        // 查询最大的ImageId并生成新的唯一ID
                        var maxImageId = await _imageRepository.GetAll()
                            .OrderByDescending(x => x.ImageId)
                            .Select(x => x.ImageId)
                            .FirstOrDefaultAsync();

                        int nextNumber = 1;
                        if (!string.IsNullOrEmpty(maxImageId) && maxImageId.StartsWith("E") && maxImageId.Length >= 4)
                        {
                            if (int.TryParse(maxImageId.Substring(1), out int currentNumber))
                            {
                                nextNumber = currentNumber + 1;
                            }
                        }

                        // 设置新的唯一ID
                        imageInfo.ImageId = $"E{nextNumber.ToString().PadLeft(3, '0')}";

                        // 保存图片信息到数据库
                        await _imageRepository.AddAsync(imageInfo);
                        savedImages.Add(imageInfo);

                        // 添加图片ID到响应中
                        imageResponse.ImageId = imageInfo.ImageId;

                        successResults.Add(imageResponse);

                        results.Add(new
                        {
                            fileName = file.FileName,
                            success = true,
                            data = imageResponse
                        });
                    }
                    else
                    {
                        _logger.LogError("图片上传失败：{FileName}, {BucketName}/{ErrorMessage}", file.FileName, bucketName);
                        results.Add(new
                        {
                            fileName = file.FileName,
                            success = false,
                            message = "上传失败",

                        });
                        failedCount++;
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "图片上传过程中发生错误：{FileName}, {BucketName}", file.FileName, bucketName);
                    results.Add(new
                    {
                        fileName = file.FileName,
                        success = false,
                        message = "上传过程中发生错误",
                        error = ex.Message
                    });
                    failedCount++;
                }
            }

            if (failedCount == files.Count)
            {
                return StatusCode(500, new
                {
                    success = false,
                    message = "所有图片上传失败",
                    results
                });
            }
            else if (failedCount > 0)
            {
                return Ok(new
                {
                    success = true,
                    message = $"部分图片上传成功，{failedCount}张上传失败",
                    data = successResults,
                    savedImages = savedImages.Select(img => img.ImageId),
                    results
                });
            }
            else
            {
                return Ok(new
                {
                    success = true,
                    message = "所有图片上传成功",
                    data = successResults,
                    savedImages = savedImages.Select(img => img.ImageId)
                });
            }
        }


        /// <summary>
        /// 删除图片
        /// </summary>
        /// <param name="objectName">对象名称（文件名或图片ID）</param>
        /// <returns>删除结果</returns>
        [HttpDelete]
        public async Task<IActionResult> Delete([FromQuery] string objectName)
        {
            if (string.IsNullOrEmpty(objectName))
            {
                return BadRequest(new { success = false, message = "对象名称不能为空" });
            }

            try
            {
                // 获取七牛云配置
                string ak = _sysConfig["OSSType:Qiniu:AccessKey"];
                string sk = _sysConfig["OSSType:Qiniu:SecretKey"];
                string bucket = _sysConfig["OSSType:Qiniu:Bucket"];
                string baseUrl = _sysConfig["OSSType:Qiniu:BaseUrl"];
                
                // 从数据库查询图片信息
                var imageInfo = await _imageRepository.GetAll()
                    .FirstOrDefaultAsync(x => x.ImageId == objectName);
                
                if (imageInfo == null)
                {
                    return NotFound(new { success = false, message = "图片不存在" });
                }
                
                // 从URL中提取文件路径
                string fileUrl = imageInfo.ImageUrl;
                
                // 提取文件名
                string fileName = Path.GetFileName(fileUrl);
                if (string.IsNullOrEmpty(fileName))
                {
                    // 如果无法从URL提取文件名，则尝试从URL的最后一部分获取
                    Uri uri;
                    if (Uri.TryCreate(fileUrl, UriKind.Absolute, out uri))
                    {
                        fileName = Path.GetFileName(uri.LocalPath);
                    }
                }
                
                // 如果仍然无法获取文件名，使用objectName作为最后的尝试
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = objectName;
                }
                
                // 构建七牛云的saveKey
                string saveKey = $"Images/traceabilityImg/{fileName}";
                
                _logger.LogInformation("尝试删除七牛云文件：Bucket={Bucket}, SaveKey={SaveKey}, URL={URL}", bucket, saveKey, fileUrl);
                
                // 删除文件
                var result = await QiNiuHelper.QiNiuDeleteFile(ak, sk, saveKey, bucket);
                if (result.Success == true)
                {
                    // 删除数据库记录
                    await _imageRepository.DeleteAsync(imageInfo);
                    
                    _logger.LogInformation("图片删除成功：{ObjectName}", objectName);
                    return Ok(new { success = true, message = "图片删除成功" });
                }
                else
                {
                    _logger.LogError("图片删除失败：{ObjectName}", objectName);
                    return StatusCode(500, new { success = false, message = "图片删除失败" });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "图片删除过程中发生错误：{ObjectName}", objectName);
                return StatusCode(500, new { success = false, message = "图片删除过程中发生错误", error = ex.Message });
            }
        }



        /// <summary>
        /// 查询图片信息
        /// </summary>
        /// <param name="command">查询命令</param>
        /// <returns>查询结果</returns>
        [HttpGet("Query")]
        public async Task<IActionResult> Query([FromQuery] QueryImageInfoCommand command)
        {
            var handler = HttpContext.RequestServices.GetRequiredService<QueryImageInfoCommandHandler>();
            var result = await handler.Handle(command);
            return Ok(result);
        }

        /// <summary>
        /// 获取图片详情
        /// </summary>
        /// <param name="imageId">图片ID</param>
        /// <returns>图片详情</returns>
        [HttpGet("{imageId}")]
        public async Task<IActionResult> GetDetail(string imageId)
        {
            if (string.IsNullOrEmpty(imageId))
            {
                return BadRequest(new ApiResult<object>(ResultCode.参数错误, "图片ID不能为空"));
            }

            try
            {
                var imageInfo = await _imageRepository.GetAll()
                    .FirstOrDefaultAsync(x => x.ImageId == imageId);

                if (imageInfo == null)
                {
                    return NotFound(new ApiResult<object>(ResultCode.资源不存在, "图片不存在"));
                }

                var mapper = HttpContext.RequestServices.GetRequiredService<IMapper>();
                var imageInfoDto = mapper.Map<ImageInfoDto>(imageInfo);

                return Ok(new ApiResult<ImageInfoDto>(ResultCode.成功, "查询成功", imageInfoDto));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取图片详情时发生错误：{ImageId}", imageId);
                return StatusCode(500, new ApiResult<object>(ResultCode.服务器错误, ex.Message));
            }
        }
    }

    /// <summary>
    /// Base64图片请求
    /// </summary>
    public class Base64ImageRequest
    {
        /// <summary>
        /// Base64图片数据
        /// </summary>
        public string Base64Data { get; set; } = string.Empty;

        /// <summary>
        /// 文件类型（如：jpg、png等）
        /// </summary>
        public string? FileType { get; set; }

        /// <summary>
        /// 图片分类（如：养殖环境/生产加工/检验报告）
        /// </summary>
        public string? ImageCategory { get; set; }

        /// <summary>
        /// 关联的生产批次
        /// </summary>
        public string? ProductionBatch { get; set; }

        /// <summary>
        /// 存储桶名称（必填）
        /// </summary>
        public string BucketName { get; set; } = string.Empty;
    }
}